using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;

namespace Sunny.UI;

public static class ConfigHelper
{
	public static Tuple<string, string> GetConfigFile<TConfig>()
	{
		string item = "配置文件";
		ConfigFileAttribute customAttribute = typeof(TConfig).GetCustomAttribute<ConfigFileAttribute>();
		string item2;
		if (customAttribute == null || customAttribute.FileName.IsNullOrWhiteSpace())
		{
			item2 = typeof(TConfig).Name + ".cfg";
		}
		else
		{
			item2 = customAttribute.FileName;
			if (!customAttribute.Description.IsNullOrEmpty())
			{
				item = customAttribute.Description;
			}
		}
		return new Tuple<string, string>(item2, item);
	}

	public static ConcurrentDictionary<string, Ident> InitIdents<TConfig>(TConfig config)
	{
		ConcurrentDictionary<string, Ident> concurrentDictionary = new ConcurrentDictionary<string, Ident>();
		foreach (PropertyInfo needProperty in config.GetType().GetNeedProperties())
		{
			Ident ident = new Ident
			{
				Key = needProperty.Name,
				Show = true,
				Description = needProperty.Description(),
				IsList = needProperty.PropertyType.IsList()
			};
			ConfigSectionAttribute customAttribute = needProperty.GetCustomAttribute<ConfigSectionAttribute>();
			ident.Section = ((customAttribute != null) ? customAttribute.Section : "");
			ConfigPropertyAttribute customAttribute2 = needProperty.GetCustomAttribute<ConfigPropertyAttribute>();
			ident.Caption = ((customAttribute2 != null) ? customAttribute2.Caption : "");
			ident.Unit = ((customAttribute2 != null) ? customAttribute2.Unit : "");
			ident.Description = ((customAttribute2 != null) ? customAttribute2.Description : "");
			ConfigIndexAttribute customAttribute3 = needProperty.GetCustomAttribute<ConfigIndexAttribute>();
			ident.Index = customAttribute3?.Index ?? (32767 + concurrentDictionary.Count);
			ident.Show = customAttribute3?.Show ?? true;
			if (ident.Description.IsNullOrEmpty())
			{
				ident.Description = needProperty.DisplayName() ?? needProperty.Description();
			}
			if (ident.Description.IsNullOrEmpty())
			{
				ident.Description = "";
			}
			if (!concurrentDictionary.ContainsKey(ident.Key))
			{
				concurrentDictionary.TryAdd(ident.Key, ident);
			}
		}
		return concurrentDictionary;
	}

	public static object DefaultValue(Type targetType)
	{
		if (!targetType.IsValueType)
		{
			return null;
		}
		return Activator.CreateInstance(targetType);
	}

	public static void LoadConfigValue<TConfig>(TConfig config, ConcurrentDictionary<string, Ident> idents)
	{
		foreach (PropertyInfo needProperty in config.GetType().GetNeedProperties())
		{
			object value = needProperty.GetValue(config, null);
			Type propertyType = needProperty.PropertyType;
			if (propertyType == typeof(string))
			{
				object value2 = idents[needProperty.Name].Value;
				needProperty.SetValue(config, Convert.ChangeType((value2 == null) ? value : value2, propertyType), null);
				continue;
			}
			if (ConvertEx.CanConvent(propertyType))
			{
				object value3 = ConvertEx.StringToObject(idents[needProperty.Name].Value, propertyType, value);
				needProperty.SetValue(config, Convert.ChangeType(value3, propertyType), null);
				continue;
			}
			if (propertyType.IsList())
			{
				Type[] genericArguments = propertyType.GetGenericArguments();
				if (genericArguments.Length != 1)
				{
					throw new ApplicationException("转换出错: " + propertyType.FullName);
				}
				Type type = genericArguments[0];
				Type type2 = typeof(List<>).MakeGenericType(type);
				MethodInfo method = type2.GetMethod("Add", BindingFlags.Instance | BindingFlags.Public);
				if (method == null)
				{
					continue;
				}
				object obj = type2.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, null, new object[0]);
				foreach (string value4 in idents[needProperty.Name].Values)
				{
					if (type == typeof(string))
					{
						object obj2 = value4;
						method.Invoke(obj, new object[1] { obj2 });
					}
					else if (ConvertEx.CanConvent(type))
					{
						object obj3 = ConvertEx.StringToObject(value4, type, DefaultValue(type));
						method.Invoke(obj, new object[1] { obj3 });
					}
				}
				needProperty.SetValue(config, obj, null);
				continue;
			}
			throw new ApplicationException("不支持此类型: " + propertyType.FullName);
		}
	}

	public static void SaveConfigValue<TConfig>(TConfig config, ConcurrentDictionary<string, Ident> idents)
	{
		foreach (PropertyInfo needProperty in config.GetType().GetNeedProperties())
		{
			object value = needProperty.GetValue(config, null);
			Type propertyType = needProperty.PropertyType;
			if (ConvertEx.CanConvent(propertyType))
			{
				string value2 = ConvertEx.ObjectToString(value, propertyType);
				idents[needProperty.Name].Value = value2;
				continue;
			}
			if (propertyType.IsList())
			{
				Type[] genericArguments = propertyType.GetGenericArguments();
				if (genericArguments.Length != 1)
				{
					throw new ApplicationException("转换出错: " + propertyType.FullName);
				}
				Type type = genericArguments[0];
				IEnumerable obj = (value as IEnumerable) ?? throw new ApplicationException("转换出错: " + propertyType.FullName);
				idents[needProperty.Name].Values.Clear();
				foreach (object item in obj)
				{
					if (ConvertEx.CanConvent(type))
					{
						idents[needProperty.Name].Values.Add(ConvertEx.ObjectToString(item, type));
						continue;
					}
					throw new ApplicationException("不支持此类型: " + propertyType.FullName);
				}
				continue;
			}
			throw new ApplicationException("不支持此类型: " + propertyType.FullName);
		}
	}
}
